package com.cryptoneedle.center.doris.service.ods;

import cn.hutool.v7.core.bean.BeanUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.cryptoneedle.center.common.constants.CommonConstant;
import com.cryptoneedle.center.common.entity.doris.DorisColumn;
import com.cryptoneedle.center.common.entity.doris.DorisTable;
import com.cryptoneedle.center.common.entity.ods.OdsColumn;
import com.cryptoneedle.center.common.entity.ods.OdsTable;
import com.cryptoneedle.center.common.repository.ods.OdsColumnRepository;
import com.cryptoneedle.center.common.repository.ods.OdsTableRepository;
import com.cryptoneedle.center.doris.service.doris.DorisColumnService;
import com.cryptoneedle.center.doris.service.doris.DorisTableService;
import com.cryptoneedle.center.source.helper.ConfigPropertyHelper;
import com.google.common.collect.Maps;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * <p>description:  </p>
 *
 * @author CryptoNeedle
 * @date 2025-09-26
 */
@Service
@DS("pg")
@Slf4j
public class OdsSyncService {

    @Resource
    private DorisTableService dorisTableService;

    @Resource
    private OdsTableRepository odsTableRepository;

    @Resource
    private DorisColumnService dorisColumnService;

    @Resource
    private OdsColumnRepository odsColumnRepository;

    public void syncOds() {
        syncTable();
        syncOdsColumn();
    }

    public void syncTable() {
        // 查询所有
        List<OdsTable> originList = odsTableRepository.list();
        Map<String, OdsTable> originMap = Maps.uniqueIndex(originList, OdsTable::getKeyString);

        // 待同步数据
        List<DorisTable> rearDealList = dorisTableService.listByDatabase(CommonConstant.DORIS_CATALOG, ConfigPropertyHelper.ods());
        Map<String, DorisTable> realDealMap = Maps.uniqueIndex(rearDealList, DorisTable::getKeyString);

        List<OdsTable> dealList = rearDealList
                .stream()
                .map(deal -> BeanUtil.copyProperties(deal, OdsTable.class))
                .toList();
        Map<String, OdsTable> dealMap = Maps.uniqueIndex(dealList, OdsTable::getKeyString);

        // 新增数据
        List<OdsTable> addList = dealList.stream().filter(deal -> !originMap.containsKey(deal.getKeyString())).toList();

        // 移除数据
        List<OdsTable> removeList = originList.stream().filter(item -> !dealMap.containsKey(item.getKeyString())).toList();

        // 保存数据 由于 origin 包含 deal 所有字段，此处使用 originList 作为驱动列表并直接通过属性拷贝赋值
        List<OdsTable> saveList = originList
                .stream()
                .filter(origin -> dealMap.containsKey(origin.getKeyString()))
                .peek(origin -> {
                    DorisTable realDeal = realDealMap.get(origin.getKeyString());
                    BeanUtil.copyProperties(realDeal, origin);
                })
                .toList();

        odsTableRepository.saveAll(addList);
        odsTableRepository.saveAll(saveList);
        odsTableRepository.deleteAll(removeList);
    }

    public void syncOdsColumn() {
        // 查询所有
        List<OdsColumn> originList = odsColumnRepository.list();
        Map<String, OdsColumn> originMap = Maps.uniqueIndex(originList, OdsColumn::getKeyString);

        // 待同步数据
        List<DorisColumn> realDealList = dorisColumnService.listByDatabase(CommonConstant.DORIS_CATALOG, ConfigPropertyHelper.ods());
        Map<String, DorisColumn> realDealMap = Maps.uniqueIndex(realDealList, DorisColumn::getKeyString);

        List<OdsColumn> dealList = realDealList
                .stream()
                .map(deal -> BeanUtil.copyProperties(deal, OdsColumn.class))
                .toList();
        Map<String, OdsColumn> dealMap = Maps.uniqueIndex(dealList, OdsColumn::getKeyString);

        // 新增数据
        List<OdsColumn> addList = dealList.stream().filter(deal -> !originMap.containsKey(deal.getKeyString())).toList();

        // 移除数据
        List<OdsColumn> removeList = originList.stream().filter(item -> !dealMap.containsKey(item.getKeyString())).toList();

        // 保存数据 由于 origin 包含 deal 所有字段，此处使用 originList 作为驱动列表并直接通过属性拷贝赋值
        List<OdsColumn> saveList = originList
                .stream()
                .filter(origin -> dealMap.containsKey(origin.getKeyString()))
                .peek(origin -> {
                    DorisColumn realDeal = realDealMap.get(origin.getKeyString());
                    BeanUtil.copyProperties(realDeal, origin);
                })
                .toList();

        odsColumnRepository.saveAll(addList);
        odsColumnRepository.saveAll(saveList);
        odsColumnRepository.deleteAll(removeList);
    }

    public void syncOdsColumn(String catalogName, String databaseName, String tableName) {
        // 查询所有
        List<OdsColumn> originList = odsColumnRepository.listByTable(catalogName, databaseName, tableName);
        Map<String, OdsColumn> originMap = Maps.uniqueIndex(originList, OdsColumn::getKeyString);

        // 待同步数据
        List<DorisColumn> realDealList = dorisColumnService.listByTable(catalogName,databaseName, tableName);
        Map<String, DorisColumn> realDealMap = Maps.uniqueIndex(realDealList, DorisColumn::getKeyString);

        List<OdsColumn> dealList = realDealList
                .stream()
                .map(deal -> BeanUtil.copyProperties(deal, OdsColumn.class))
                .toList();
        Map<String, OdsColumn> dealMap = Maps.uniqueIndex(dealList, OdsColumn::getKeyString);

        // 新增数据
        List<OdsColumn> addList = dealList.stream().filter(deal -> !originMap.containsKey(deal.getKeyString())).toList();

        // 移除数据
        List<OdsColumn> removeList = originList.stream().filter(item -> !dealMap.containsKey(item.getKeyString())).toList();

        // 保存数据 由于 origin 包含 deal 所有字段，此处使用 originList 作为驱动列表并直接通过属性拷贝赋值
        List<OdsColumn> saveList = originList
                .stream()
                .filter(origin -> dealMap.containsKey(origin.getKeyString()))
                .peek(origin -> {
                    DorisColumn realDeal = realDealMap.get(origin.getKeyString());
                    BeanUtil.copyProperties(realDeal, origin);
                })
                .toList();

        odsColumnRepository.saveAll(addList);
        odsColumnRepository.saveAll(saveList);
        odsColumnRepository.deleteAll(removeList);
    }
}